// HTTP proxy implementation

use crate::HysteriaClient;
use std::sync::Arc;
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::TcpStream;
use tracing::{debug, warn};

pub async fn handle_http(
    mut socket: TcpStream,
    _client: Arc<HysteriaClient>,
) -> anyhow::Result<()> {
    let mut reader = BufReader::new(&mut socket);
    let mut request_line = String::new();
    
    // Read request line
    reader.read_line(&mut request_line).await?;
    
    let parts: Vec<&str> = request_line.split_whitespace().collect();
    if parts.len() < 3 {
        warn!("Invalid HTTP request");
        return Ok(());
    }

    let method = parts[0];
    let url = parts[1];

    debug!("HTTP request: {} {}", method, url);

    if method == "CONNECT" {
        // HTTPS proxy (CONNECT method)
        handle_connect(&mut socket, url).await?;
    } else {
        // HTTP proxy
        handle_http_request(&mut socket, &request_line).await?;
    }

    Ok(())
}

async fn handle_connect(socket: &mut TcpStream, target: &str) -> anyhow::Result<()> {
    // Parse host:port
    let addr = target.to_string();
    
    // Connect to target
    match TcpStream::connect(&addr).await {
        Ok(mut target) => {
            // Send 200 Connection Established
            socket.write_all(b"HTTP/1.1 200 Connection Established\r\n\r\n").await?;
            
            // Relay data
            let (mut client_read, mut client_write) = socket.split();
            let (mut target_read, mut target_write) = target.split();

            let client_to_target = async {
                tokio::io::copy(&mut client_read, &mut target_write).await
            };

            let target_to_client = async {
                tokio::io::copy(&mut target_read, &mut client_write).await
            };

            tokio::try_join!(client_to_target, target_to_client)?;
        }
        Err(_) => {
            socket.write_all(b"HTTP/1.1 502 Bad Gateway\r\n\r\n").await?;
        }
    }

    Ok(())
}

async fn handle_http_request(socket: &mut TcpStream, _request: &str) -> anyhow::Result<()> {
    // TODO: Implement HTTP proxy (non-CONNECT)
    socket.write_all(b"HTTP/1.1 501 Not Implemented\r\n\r\n").await?;
    Ok(())
}
